package vader.tableStore.impl;

import com.alibaba.fastjson.JSONObject;
import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.model.*;
import com.alicloud.openservices.tablestore.model.search.SearchQuery;
import com.alicloud.openservices.tablestore.model.search.SearchRequest;
import com.alicloud.openservices.tablestore.model.search.SearchResponse;
import com.alicloud.openservices.tablestore.model.search.query.*;
import com.alicloud.openservices.tablestore.model.search.sort.FieldSort;
import com.alicloud.openservices.tablestore.model.search.sort.PrimaryKeySort;
import com.alicloud.openservices.tablestore.model.search.sort.Sort;
import com.alicloud.openservices.tablestore.model.search.sort.SortOrder;
import com.alicloud.openservices.tablestore.model.sql.*;
import com.fancy.cc.common.api.CommonPage;
import com.fancy.cc.common.tableStore.TablestoreService;
import com.fancy.cc.common.tableStore.util.TableStoreUtil;
import com.fancy.cc.common.util.CommonUtils;
import com.fancy.cc.common.util.ValidatorUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author: yongxin@mail.thefancyapp.com
 * @program: fancy_bos
 * @description: tableStore实现类
 * @create: 2020-12-08 17:58
 **/
@Slf4j
@Service
@ConditionalOnProperty(prefix = "tablestore", name = "enable", havingValue = "true")
public class TablestoreServiceImpl implements TablestoreService {
    @Resource
    private SyncClient syncClient;

    @Override
    public Boolean createTable(Class clazz) {
        try {
            syncClient.createTable(TableStoreUtil.buildCreateTable(clazz));
            return true;
        } catch (Exception e) {
            log.error("createTableException:{}", clazz, e);
        }
        return false;
    }


    @Override
    public Boolean deleteTable(Class clazz) {
        try {
            DeleteTableRequest request = new DeleteTableRequest(TableStoreUtil.getTableName(clazz));
            syncClient.deleteTable(request);
            return true;
        } catch (Exception e) {
            log.error("deleteTableException:{}", clazz, e);
        }
        return false;
    }

    @Override
    public <T> T getData(Object obj) {
        Class clazz = obj.getClass();
        try {
            PrimaryKey primaryKey = TableStoreUtil.parsePrimaryKey(obj);
            if (primaryKey == null) {
                return null;
            }
            SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TableStoreUtil.getTableName(clazz), primaryKey);
            //读取最新版本
            criteria.setMaxVersions(1);
            TableStoreUtil.buildQuery(clazz, criteria);
            GetRowResponse getRowResponse = syncClient.getRow(new GetRowRequest(criteria));
            if (getRowResponse == null || getRowResponse.getRow() == null) {
                return null;
            }
            return TableStoreUtil.parseRow(clazz, getRowResponse.getRow());
        } catch (Exception e) {
            log.error("getRowException:{}", obj, e);
        }
        return null;
    }

    @Override
    public boolean deleteData(Object obj) {
        try {
            RowDeleteChange rowDeleteChange = new RowDeleteChange(TableStoreUtil.getTableName(obj.getClass()), TableStoreUtil.parsePrimaryKey(obj));
            DeleteRowResponse deleteRowResponse = syncClient.deleteRow(new DeleteRowRequest(rowDeleteChange));
            if (deleteRowResponse != null) {
                return true;
            }
        } catch (Exception e) {
            log.error("deleteDataException:{}", obj, e);
        }
        return false;
    }

    @Override
    public boolean updateData(Object obj) {
        try {
            RowUpdateChange rowUpdateChange = TableStoreUtil.buildUpdate(obj);
            UpdateRowResponse updateRowResponse = syncClient.updateRow(new UpdateRowRequest(rowUpdateChange));
            if (updateRowResponse != null) {
                return true;
            }
        } catch (Exception e) {
            log.error("updateDataException:{}", obj, e);
        }
        return false;
    }

    @Override
    public boolean putData(Object obj) {
        try {
            RowPutChange rowPutChange = TableStoreUtil.buildPut(obj);
            rowPutChange.setReturnType(ReturnType.RT_PK);
            PutRowResponse putRowResponse = syncClient.putRow(new PutRowRequest(rowPutChange));
            if (putRowResponse != null) {
                return true;
            }
        } catch (Exception e) {
            log.error("putDataException:{}", obj, e);
        }
        return false;
    }

    @Override
    public <T> void batchPutData(List<T> objectList) {
        if (CollectionUtils.isEmpty(objectList)) {
            return;
        }
        if (objectList.size() > 100) {
            //todo
        }
        try {
            BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest();
            for (T obj : objectList) {
                RowPutChange rowPutChange = TableStoreUtil.buildPut(obj);
                batchWriteRowRequest.addRowChange(rowPutChange);
            }
            BatchWriteRowResponse response = syncClient.batchWriteRow(batchWriteRowRequest);
            int tryNum = 0;
            int totalRetry = 3;
            while (!response.isAllSucceed() && tryNum < totalRetry) {
                BatchWriteRowRequest retryRequest = batchWriteRowRequest.createRequestForRetry(response.getFailedRows());
                response = syncClient.batchWriteRow(retryRequest);
                tryNum++;
                if (tryNum >= totalRetry && !response.isAllSucceed()) {
                    log.error("batchPutRowTooMuch:{}", response.getFailedRows());
                }
            }
        } catch (Exception e) {
            log.error("batchPutDataException:{}", objectList, e);
        }
    }


    @Override
    public <T> List<T> batchGetData(List<T> objectList) {
        List<T> newObjList = new ArrayList<>();
        if (CollectionUtils.isEmpty(objectList)) {
            return newObjList;
        }
        try {
            Class clazz = objectList.get(0).getClass();
            MultiRowQueryCriteria multiRowQueryCriteria = new MultiRowQueryCriteria(TableStoreUtil.getTableName(clazz));
            multiRowQueryCriteria.setMaxVersions(1);
            TableStoreUtil.buildQuery(clazz, multiRowQueryCriteria);
            for (T obj : objectList) {
                multiRowQueryCriteria.addRow(TableStoreUtil.parsePrimaryKey(obj));
            }
//            multiRowQueryCriteria.addColumnsToGet("itemId");
//            SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("itemId",
//                    SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("10025831408"));
//            singleColumnValueFilter.setPassIfMissing(false);
//            multiRowQueryCriteria.setFilter(singleColumnValueFilter);

            BatchGetRowRequest batchGetRowRequest = new BatchGetRowRequest();
            batchGetRowRequest.addMultiRowQueryCriteria(multiRowQueryCriteria);
            BatchGetRowResponse batchGetRowResponse = syncClient.batchGetRow(batchGetRowRequest);
            if (CollectionUtils.isEmpty(batchGetRowResponse.getSucceedRows())) {
                return newObjList;
            }
            List<BatchGetRowResponse.RowResult> rowResults = batchGetRowResponse.getSucceedRows();
            for (BatchGetRowResponse.RowResult rowResult : rowResults) {
                if (rowResult.getRow() == null) {
                    continue;
                }
                newObjList.add(TableStoreUtil.parseRow(clazz, rowResult.getRow()));
            }
        } catch (Exception e) {
            log.error("batchGetDataException:{}", objectList, e);
        }
        return newObjList;
    }


    @Override
    public <T> List<T> getRangeData(T begin, T end) {
        List<T> objList = new ArrayList<>();
        try {
            if (begin == null || end == null) {
                return objList;
            }
            PrimaryKey startPrimaryKey = TableStoreUtil.parsePrimaryKey(begin);
            PrimaryKey endPrimaryKey = TableStoreUtil.parsePrimaryKey(end);
            if (startPrimaryKey == null || endPrimaryKey == null) {
                return objList;
            }
            Class<?> clazz = begin.getClass();
            RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TableStoreUtil.getTableName(clazz));
            rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKey);
            rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKey);
            rangeRowQueryCriteria.setMaxVersions(1);
            while (true) {
                GetRangeResponse getRangeResponse = syncClient.getRange(new GetRangeRequest(rangeRowQueryCriteria));
                for (Row row : getRangeResponse.getRows()) {
                    T rowObj = TableStoreUtil.parseRow(clazz, row);
                    if (rowObj == null) {
                        continue;
                    }
                    objList.add(rowObj);
                }
                if (getRangeResponse.getNextStartPrimaryKey() == null) {
                    break;
                }
                rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
            }
        } catch (Exception e) {
            log.error("getRangeException:{},{}", begin, end, e);
        }
        return objList;
    }

    @Override
    public <T> List<T> searchData(Object obj, String indexFieldName, String query) {
        List<T> objList = new ArrayList<>();
        Class<?> clazz = obj.getClass();
        String tableName = TableStoreUtil.getTableName(clazz);
        String indexName = TableStoreUtil.getMultiIndexName(clazz);
        SearchQuery searchQuery = new SearchQuery();
        BoolQuery boolQuery = new BoolQuery();
        MatchQuery matchQuery = new MatchQuery(); // 设置查询类型为MatchQuery
        matchQuery.setFieldName(indexFieldName); // 设置要匹配的字段
        matchQuery.setText(query); // 设置要匹配的值
        List<Query> querys = new ArrayList<Query>();
        querys.add(matchQuery);
        boolQuery.setMustQueries(querys);
        searchQuery.setQuery(boolQuery);
        // 设置返回所有列
        SearchRequest searchRequest = new SearchRequest(tableName, indexName, searchQuery);
        SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
        columnsToGet.setReturnAll(true);
        searchRequest.setColumnsToGet(columnsToGet);

        SearchResponse searchResponse = syncClient.search(searchRequest);
        for (Row row : searchResponse.getRows()) {
            T rowObj = TableStoreUtil.parseRow(clazz, row);
            if (rowObj == null) {
                continue;
            }
            objList.add(rowObj);
        }
        return objList;
    }

    @Override
    public <T> List<T> searchDataRange(Object obj, String minTime, String maxTime, String query, Map<String, Object> queryMap, Integer limitNum, String orderByParams, String orderByType) {
        List<T> objList = new ArrayList<>();
        Class<?> clazz = obj.getClass();
        String tableName = TableStoreUtil.getTableName(clazz);
        String indexName = TableStoreUtil.getMultiIndexName(clazz);
        SearchQuery searchQuery = new SearchQuery();
        BoolQuery boolQuery = new BoolQuery();
        List<Query> querys = new ArrayList<Query>();
        if (CommonUtils.notNull(maxTime) && CommonUtils.notNull(minTime)) {
            RangeQuery rangeQuery = new RangeQuery();
            rangeQuery.lessThan(ColumnValue.fromString(maxTime));
            rangeQuery.greaterThan(ColumnValue.fromString(minTime));
            rangeQuery.setIncludeLower(true);
            rangeQuery.setIncludeUpper(true);
            rangeQuery.setFieldName(query);
            querys.add(rangeQuery);
        }
        //多元索引 具有多个值的情况
        if (queryMap.size() > 0) {
            queryMap.forEach((key, value) -> {
                MatchQuery matchQuery = new MatchQuery(); // 设置查询类型为MatchQuery
                matchQuery.setFieldName(key); // 设置要匹配的字段
                matchQuery.setText(value.toString()); // 设置要匹配的值
                querys.add(matchQuery);
            });
        }
        boolQuery.setMustQueries(querys);
        searchQuery.setQuery(boolQuery);
        if (!ValidatorUtils.empty(orderByParams)) {
            if ("DESC".equals(orderByType)) {
                searchQuery.setSort(new Sort(Arrays.asList(new FieldSort(orderByParams, SortOrder.DESC))));
            } else {
                searchQuery.setSort(new Sort(Arrays.asList(new FieldSort(orderByParams, SortOrder.ASC))));
            }

        }
        if (limitNum > 0) {
            searchQuery.setOffset(0); //设置默认的offset为0。
            searchQuery.setLimit(limitNum); //设置limit最多100条  [search.limit] must be less than 100, current limit is Integer.MAX_VALUE =2147483647
            searchQuery.setGetTotalCount(true); //设置返回匹配的总行数。
        }
        // 设置返回所有列
        SearchRequest searchRequest = new SearchRequest(tableName, indexName, searchQuery);
        SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
        columnsToGet.setReturnAll(true);
        searchRequest.setColumnsToGet(columnsToGet);
        SearchResponse searchResponse = syncClient.search(searchRequest);
        for (Row row : searchResponse.getRows()) {
            T rowObj = TableStoreUtil.parseRow(clazz, row);
            if (rowObj == null) {
                continue;
            }
            objList.add(rowObj);
        }
        return objList;
    }

    @Override
    public <T> List<T> searchMultiIndexData(Object obj, Map<String, String> indexFields, Boolean isFullRow) {
        Integer maxLimit = 100;
        List<T> objList = new ArrayList<>();
        Class<?> clazz = obj.getClass();
        String tableName = TableStoreUtil.getTableName(clazz);
        String indexName = TableStoreUtil.getMultiIndexName(clazz);
        SearchQuery searchQuery = new SearchQuery();
        BoolQuery boolQuery = new BoolQuery();
        List<Query> querys = new ArrayList<Query>();
        //多元索引 具有多个值的情况
        indexFields.forEach((key, value) -> {
            MatchQuery matchQuery = new MatchQuery(); // 设置查询类型为MatchQuery
            matchQuery.setFieldName(key); // 设置要匹配的字段
            matchQuery.setText(value); // 设置要匹配的值
            querys.add(matchQuery);
        });
        boolQuery.setMustQueries(querys);
        searchQuery.setQuery(boolQuery);
        Boolean isNextSearch = true;
        Integer offset = 0;
        while (isNextSearch) {
            if (isFullRow) {
                searchQuery.setOffset(offset); //设置默认的offset为0。
                searchQuery.setLimit(maxLimit); //设置limit最多100条  [search.limit] must be less than 100, current limit is Integer.MAX_VALUE =2147483647
                searchQuery.setGetTotalCount(true); //设置返回匹配的总行数。
            }
            // 设置返回所有列
            SearchRequest searchRequest = new SearchRequest(tableName, indexName, searchQuery);
            SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
            columnsToGet.setReturnAll(true);
            searchRequest.setColumnsToGet(columnsToGet);
            SearchResponse searchResponse = syncClient.search(searchRequest);
            for (Row row : searchResponse.getRows()) {
                T rowObj = TableStoreUtil.parseRow(clazz, row);
                if (rowObj == null) {
                    continue;
                }
                objList.add(rowObj);
            }
            if (isFullRow) {
                if (searchResponse.getTotalCount() <= objList.size()) {
                    isNextSearch = false;
                } else {
                    offset = offset + maxLimit;
                }
            } else {
                isNextSearch = false;
            }
        }
        return objList;
    }


    /**
     * 翻页查询
     */
    @Override
    public <T> CommonPage<T> getDataByPage(Object obj, Integer pageNum, Integer pageSize) {
        Integer offset = pageSize * (pageNum - 1);
        List<T> objList = new ArrayList<>();
        Class<?> clazz = obj.getClass();
        String tableName = TableStoreUtil.getTableName(clazz);
        String indexName = TableStoreUtil.getMultiIndexName(clazz);
        SearchQuery searchQuery = new SearchQuery();
        searchQuery.setSort(new Sort(Arrays.asList(new PrimaryKeySort()))); //正序。
        searchQuery.setQuery(new MatchAllQuery());
        searchQuery.setGetTotalCount(true);//设置返回匹配的总行数。
        searchQuery.setLimit(pageSize);
        searchQuery.setOffset(offset);

        SearchRequest searchRequest = new SearchRequest(tableName, indexName, searchQuery);
        //通过设置columnsToGet参数可以指定返回的列或返回所有列，如果不设置此参数，则默认只返回主键列。
        SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
        columnsToGet.setReturnAll(true); //设置为返回所有列。
        //columnsToGet.setColumns(Arrays.asList("ColName1","ColName2")); //设置为返回指定列。
        searchRequest.setColumnsToGet(columnsToGet);

        SearchResponse resp = syncClient.search(searchRequest);
        if (!resp.isAllSuccess()) {
            throw new RuntimeException("not all success");
        }

        for (Row row : resp.getRows()) {
            T rowObj = TableStoreUtil.parseRow(clazz, row);
            if (rowObj == null) {
                continue;
            }
            objList.add(rowObj);
        }
        CommonPage<T> commonPage = new CommonPage<>();
        commonPage.setTotalPage(objList.size() % pageSize == 0 ? (objList.size() / pageSize) : (objList.size() / pageSize + 1));
        commonPage.setTotal(resp.getTotalCount());
        commonPage.setPageNum(pageNum);
        commonPage.setPageSize(pageSize);
        commonPage.setList(objList);
        return commonPage;
    }

    @Override
    public <T> CommonPage<T> getDataMatchQueryByPage(Object obj, Integer pageNum, Integer pageSize, Map<String, Object> matchMap, List<String> showParams, String indexName) {
        Integer offset = pageSize * (pageNum - 1);
        List<T> objList = new ArrayList<>();
        Class<?> clazz = obj.getClass();
        String tableName = TableStoreUtil.getTableName(clazz);
        //String indexName = TableStoreUtil.getMultiIndexName(clazz);
        SearchQuery searchQuery = new SearchQuery();
        if (matchMap == null || matchMap.size() == 0) {
            searchQuery.setQuery(new MatchAllQuery());
            searchQuery.setSort(new Sort(Arrays.asList(new FieldSort("createTime", SortOrder.DESC)))); //倒序
        } else {
            List<Query> matchQueries = new ArrayList<>();
            for (String key : matchMap.keySet()) {
                TermQuery termQuery = new TermQuery(); //设置查询类型为TermQuery。
                termQuery.setFieldName(key); //设置要匹配的字段。
                if ("auditing".equals(key)) {
                    Boolean auditing = (Boolean) matchMap.get(key);
                    termQuery.setTerm(ColumnValue.fromBoolean(auditing)); //设置要匹配的值。
                } else if ("articleSource".equals(key)) {
                    String articleSource = (String) matchMap.get(key);
                    termQuery.setTerm(ColumnValue.fromString(articleSource)); //设置要匹配的值。
                } else {
                    termQuery.setTerm(ColumnValue.fromString((String) matchMap.get(key))); //设置要匹配的值。
                }
                matchQueries.add(termQuery);
            }
            BoolQuery boolQuery = new BoolQuery();
            boolQuery.setMustQueries(matchQueries);
            searchQuery.setQuery(boolQuery);
//            searchQuery.setSort(new Sort(Arrays.asList(new FieldSort("time", SortOrder.DESC)))); //倒序
        }

        searchQuery.setOffset(offset); //设置offset为0。
        searchQuery.setLimit(pageSize); //设置limit为20，表示最多返回20行数据。
        searchQuery.setGetTotalCount(true); //设置返回匹配的总行数。

        SearchRequest searchRequest = new SearchRequest(tableName, indexName, searchQuery);
        //通过设置columnsToGet参数可以指定返回的列或返回所有列，如果不设置此参数，则默认只返回主键列。
        SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
        columnsToGet.setReturnAll(true); //设置为返回所有列。
        columnsToGet.setColumns(showParams); //设置为返回指定列。
        searchRequest.setColumnsToGet(columnsToGet);

        SearchResponse resp = syncClient.search(searchRequest);
        if (!resp.isAllSuccess()) {
            throw new RuntimeException("not all success");
        }

        for (Row row : resp.getRows()) {
            T rowObj = TableStoreUtil.parseRow(clazz, row);
            if (rowObj == null) {
                continue;
            }
            objList.add(rowObj);
        }
        CommonPage<T> commonPage = new CommonPage<>();
        commonPage.setTotalPage(objList.size() % pageSize == 0 ? (objList.size() / pageSize) : (objList.size() / pageSize + 1));
        commonPage.setTotal(resp.getTotalCount());
        commonPage.setPageNum(pageNum);
        commonPage.setPageSize(pageSize);
        commonPage.setList(objList);
        return commonPage;
    }

    public List<Map<String, Object>> listMapDataBySql(String sql) {
        // 创建SQL请求。
        SQLQueryRequest request = new SQLQueryRequest(sql);

        // 获取SQL的响应结果。
        SQLQueryResponse response = syncClient.sqlQuery(request);

        // 获取SQL的请求类型。
        System.out.println("response type: " + response.getSQLStatementType());

        // 获取SQL返回值的Schema。
        SQLTableMeta tableMeta = response.getSQLResultSet().getSQLTableMeta();
        System.out.println("response table meta: " + tableMeta.getSchema());

        List<Map<String, Object>> objList = new ArrayList<>();

        // 获取SQL的返回结果。
        SQLResultSet resultSet = response.getSQLResultSet();
        System.out.println("response resultset:");
        while (resultSet.hasNext()) {
            SQLRow row = resultSet.next();
            List<SQLColumnSchema> schemas = tableMeta.getSchema();
            Map<String, Object> map = new HashMap<>();
            for (int i = 0; i < schemas.size(); ++i) {
                String key = schemas.get(i).getName();
                Object value = row.get(i);
                map.put(key, value);
            }
            System.out.println(map);
            objList.add(map);
            row.toDebugString();
        }

        return objList;
    }

    @Override
    public Map<String, Object> mapDataBySql(String sql) {
        // 创建SQL请求。
        SQLQueryRequest request = new SQLQueryRequest(sql);

        // 获取SQL的响应结果。
        SQLQueryResponse response = syncClient.sqlQuery(request);

        // 获取SQL的请求类型。
        System.out.println("response type: " + response.getSQLStatementType());

        // 获取SQL返回值的Schema。
        SQLTableMeta tableMeta = response.getSQLResultSet().getSQLTableMeta();
        System.out.println("response table meta: " + tableMeta.getSchema());

        // 获取SQL的返回结果。
        SQLResultSet resultSet = response.getSQLResultSet();
        System.out.println("response resultset:");

        Map<String, Object> map = new HashMap<>();
        while (resultSet.hasNext()) {
            SQLRow row = resultSet.next();
            String key = String.valueOf(row.get(0));
            Object value = row.get(1);
            System.out.println(key+":"+JSONObject.toJSONString(value));
            map.put(key, value);
        }
        return map;
    }

    @Override
    public Object getDataBySql(String sql) {
        // 创建SQL请求。
        SQLQueryRequest request = new SQLQueryRequest(sql);

        // 获取SQL的响应结果。
        SQLQueryResponse response = syncClient.sqlQuery(request);

        // 获取SQL的请求类型。
        System.out.println("response type: " + response.getSQLStatementType());

        // 获取SQL返回值的Schema。
        SQLTableMeta tableMeta = response.getSQLResultSet().getSQLTableMeta();
        System.out.println("response table meta: " + tableMeta.getSchema());

        // 获取SQL的返回结果。
        SQLResultSet resultSet = response.getSQLResultSet();

        SQLRow row = resultSet.next();
        Object o = row.get(0);
        System.out.println("response resultset:"+JSONObject.toJSONString(o));
        return o;
    }

    @Override
    public List<String> listDataBySql(String sql) {
        // 创建SQL请求。
        SQLQueryRequest request = new SQLQueryRequest(sql);

        // 获取SQL的响应结果。
        SQLQueryResponse response = syncClient.sqlQuery(request);

        // 获取SQL的请求类型。
        System.out.println("response type: " + response.getSQLStatementType());

        // 获取SQL返回值的Schema。
        SQLTableMeta tableMeta = response.getSQLResultSet().getSQLTableMeta();
        System.out.println("response table meta: " + tableMeta.getSchema());

        // 获取SQL的返回结果。
        SQLResultSet resultSet = response.getSQLResultSet();
        System.out.println("response resultset:");

        List<String> list = new ArrayList<>();
        while (resultSet.hasNext()) {
            SQLRow row = resultSet.next();
            String json = String.valueOf(row.get(0));
            list.add(json);
            System.out.println(json);
        }
        return list;
    }

    @Override
    public List<JSONObject> listJsonDataBySql(String sql) {
        // 创建SQL请求。
        SQLQueryRequest request = new SQLQueryRequest(sql);

        // 获取SQL的响应结果。
        SQLQueryResponse response = syncClient.sqlQuery(request);

        // 获取SQL的请求类型。
        System.out.println("response type: " + response.getSQLStatementType());

        // 获取SQL返回值的Schema。
        SQLTableMeta tableMeta = response.getSQLResultSet().getSQLTableMeta();
        System.out.println("response table meta: " + tableMeta.getSchema());

        // 获取SQL的返回结果。
        SQLResultSet resultSet = response.getSQLResultSet();
        System.out.println("response resultset:");

        List<JSONObject> list = new ArrayList<>();
        while (resultSet.hasNext()) {
            SQLRow row = resultSet.next();
            List<SQLColumnSchema> schemas = tableMeta.getSchema();
            JSONObject jsonObject = new JSONObject();
            for (int i = 0; i < schemas.size(); ++i) {
                String key = schemas.get(i).getName();
                Object value = row.get(i);
                jsonObject.put(key, value);
            }
            System.out.println(jsonObject.toJSONString());
            list.add(jsonObject);
            row.toDebugString();
        }
        return list;

    }

}
